import numpy as np

from optimizer.BaseOptimizer import BaseOptimizer
from utils.Ising import Ising


class Optimizer(BaseOptimizer):
    optimizer_name = 'SB'

    def __init__(self, config: dict):
        self.ising_J = np.zeros((1, 1))
        super().__init__(config)

        self.detuning_frequency = 1  # KPO的失谐频率
        self.kerr_constant = 1  # KPO的kerr常量
        self.pressure = lambda t: 0.01 * t  # KPO泵涌压力
        self.time_step = 0.25  # 时间步长
        self.symplectic_parameter = 1  # 辛欧拉方法参数
        self.convergence_threshold = 35
        self.sampling_period = 60

        self.xi0 = 0.7 * self.detuning_frequency / (np.std(self.ising_J) * self.n_dim ** (1 / 2))

        self.symplectic_time_step = self.time_step / self.symplectic_parameter
        self.v_t = self.symplectic_time_step * self.detuning_frequency

        self.xs = 0 * np.random.uniform(self.pos_min, self.pos_max, self.xs.shape)
        self.vs = 0.01 * np.random.random(self.xs.shape)



    def run_once(self, actions=None):
        self.clip()
        self.best_update()

        self.factor = self.pressure(self.step_num * self.time_step)
        self.vs -= self.symplectic_time_step * (self.kerr_constant * self.xs ** 3 - self.factor * self.xs)
        self.vs += self.time_step * self.xi0 * (self.ising_J @ self.xs.T).T

        self.xs = self.xs + self.v_t * self.vs


